package com.example.mongodb.mongodb;

import com.example.mongodb.entity.DishesInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.geo.*;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.NearQuery;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author : zhayh
 * @date : 2021-5-16 20:59
 * @description :
 */

@Slf4j
@Service
public class RestaurantDocServiceImpl implements RestaurantDocService {
    @Resource
    private RestaurantDocRepository restaurantDocRepository;
    @Resource
    private MongoTemplate mongoTemplate;
    @Resource
    private DataQueueService dataQueueService;

    @Override
    public Page<RestaurantDoc> getAllRestaurants(Integer page, Integer size) {
        return restaurantDocRepository.findAll(PageRequest.of(page, size));
    }

    @Override
    public RestaurantDoc addRestaurant(RestaurantDoc restaurantDoc) throws Exception {
        log.info("添加餐厅信息： {}", restaurantDoc.getShopName());
        // 餐厅名称分词
        List<String> keywords = IkTools.keywords(restaurantDoc.getShopName());
        // 餐厅简介分词
        keywords.addAll(keywords.size() - 1, IkTools.keywords(restaurantDoc.getShopMemo()));
        List<DishesInfo> dishesInfos = restaurantDoc.getDishesList();
        for (DishesInfo dishesInfo : dishesInfos) {
            keywords.addAll(keywords.size() - 1, IkTools.keywords(dishesInfo.getDishesName()));
        }
        restaurantDoc.setKeywords(keywords);
        return restaurantDocRepository.save(restaurantDoc);
    }

    @Override
    public RestaurantDoc updateRestaurant(RestaurantDoc restaurantDoc) throws Exception {
        log.info("更新餐厅信息： {}", restaurantDoc.getShopName());
        // 获取已有的餐厅数据
        RestaurantDoc exist = restaurantDocRepository.findByDataId(restaurantDoc.getDataId());
        if (exist != null) {
            restaurantDoc.set_id(exist.get_id());
        }
        // 餐厅名称分词
        List<String> keywords = IkTools.keywords(restaurantDoc.getShopName());
        // 餐厅简介分词
        keywords.addAll(keywords.size() - 1, IkTools.keywords(restaurantDoc.getShopMemo()));
        List<DishesInfo> dishesInfos = restaurantDoc.getDishesList();
        for (DishesInfo dishesInfo : dishesInfos) {
            keywords.addAll(keywords.size() - 1, IkTools.keywords(dishesInfo.getDishesName()));
        }
        restaurantDoc.setKeywords(keywords);
        return restaurantDocRepository.save(restaurantDoc);
    }

    @Override
    public Boolean deleteRestaurant(Long dataId) {
        RestaurantDoc restaurantDoc = restaurantDocRepository.findByDataId(dataId);
        if (restaurantDoc != null) {
            restaurantDocRepository.delete(restaurantDoc);
            return true;
        }
        return null;
    }

    @Override
    public Page<RestaurantDoc> getRestaurantsByKeywords(String keywords, Integer page, Integer size) {
        return restaurantDocRepository.findByKeywords(keywords, PageRequest.of(page, size));
    }

    @Override
    public List<GeoResult<RestaurantDoc>> getRestaurantsByPosition(Double lon, Double lat, Long distance) {
        // 创建查询坐标点
        Point point = new Point(lon, lat);
        // 定义附近查询条件
        NearQuery query = NearQuery.near(point).maxDistance(new Distance(distance, Metrics.KILOMETERS));
        // 发送距离查询
        GeoResults<RestaurantDoc> geoResult = mongoTemplate.geoNear(query, RestaurantDoc.class, "restaurants");
        return geoResult.getContent();
    }

    /**
     * 监听新增餐厅的消息
     * @param message 餐厅Id
     */
    @RabbitListener(queues = "queue.restaurant.create")
    public void processCreateMessage(String message) {
        log.info("队列1消息处理： {}", message);
        RestaurantDoc doc = dataQueueService.getRestaurantDoc(Long.parseLong(message));
        try {
            addRestaurant(doc);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 监听更新餐厅信息的消息
     * @param message 餐厅Id
     */
    @RabbitListener(queues = "queue.restaurant.update")
    public void processUpdateMessage(String message) {
        log.info("队列2消息处理： {}", message);
        RestaurantDoc doc = dataQueueService.getRestaurantDoc(Long.parseLong(message));
        try {
            updateRestaurant(doc);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 监听餐厅创建消息
     * @param message 餐厅Id
     */
    @RabbitListener(queues = "queue.restaurant.delete")
    public void processDeleteMessage(String message) {
        log.info("队列3消息处理： {}", message);
        deleteRestaurant(Long.parseLong(message));
    }
}
